
namespace Patterns4Net.Core.AttributesPatterns
{
    using System;
    using Mono.Cecil;
    using Patterns4Net.Attributes.DesignPatterns;
    using Patterns4Net.Core.Patterns;
    using Patterns4Net.Attributes;

    public class BasicPatternCreator<TPattern> : ICreatePatternFromAttribute where TPattern : IPattern
    {
        public IPattern Crate(CustomAttribute attribute, IMemberDefinition targetType)
        {
            var ctor = typeof(TPattern).GetConstructor(new[] { targetType.GetType() });
            if (ctor == null)
            {
                throw new PatternClassShouldHaveCtorWithTypeReference();
            }

            return (IPattern)ctor.Invoke(new object[] { targetType });
        }

        public class PatternClassShouldHaveCtorWithTypeReference : ApplicationException
        {
            public PatternClassShouldHaveCtorWithTypeReference()
            {
                // TODO: message
            }
        }
    }

    [PatternCreatorExport(typeof(StrategyAttribute))]
    public class StrategyCreator : BasicPatternCreator<Strategy>
    {
    }

    [PatternCreatorExport(typeof(FactoryMethodAttribute))]
    public class FactoryMethodCreator : BasicPatternCreator<FactoryMethod>
    {
    }

    [PatternCreatorExport(typeof(TemplateMethodAttribute))]
    public class TemplateMethodCreator : BasicPatternCreator<TemplateMethod>
    {
    }

    [PatternCreatorExport(typeof(NullObjectAttribute))]
    public class NullObjectCreator : BasicPatternCreator<NullObject>
    {
    }

    [PatternCreatorExport(typeof(SimpleFactoryMethodAttribute))]
    public class SimpleFactoryMethodCreator : BasicPatternCreator<SimpleFactoryMethod>
    {
    }

    [PatternCreatorExport(typeof(PrototypeAttribute))]
    public class PrototypeCreator : BasicPatternCreator<Prototype>
    {
    }

    [PatternCreatorExport(typeof(SingletonAttribute))]
    public class SingletonCreator : BasicPatternCreator<Singleton>
    {
    }
}
